<script setup>
import { ref, toRaw, getCurrentInstance, inject, provide, nextTick } from "vue";
import { isArray, isFunction, get, cloneDeep, isUndefined } from "lodash";
import tool from "@/utils/tool";
// import { containerItems } from '@cps/wd-form/js/utils'
import { message, closeAllMessage } from "@/utils/message";
import WdForm from "@cwd/wd-form";

const columns = inject("columns");
const options = inject("options");

const dataVisible = ref(false);
const dataLoading = ref(true);
const componentName = ref("el-dialog");
const formColumns = ref([]);
const formModel = ref({});
const currentAction = ref("");
const actionTitle = ref("");
const wdFormRef = ref(null);
const formOptions = ref({ showButtons: false });

const emit = defineEmits(["success", "error"]);

if (window.screen.width < 768) {
  options.formOption.width = window.screen.width;
  options.formOption.isFull = true;
}
//编辑表单
const edit = async (data) => {
  actionTitle.value = options.edit.title ?? "编辑";
  currentAction.value = "edit";
  for (let i in data) formModel.value[i] = data[i];
  open(data);
};
//新增
const add = async () => {
  actionTitle.value = "新增";
  currentAction.value = "add";
  formModel.value = {};
  open();
};
//查看详情
const see = async (data) => {
  
  currentAction.value = "see";
  actionTitle.value = options.edit.title ?? "详情";
  for (let i in data) formModel.value[i] = data[i];
  open(data);
};
//打开对话框
const open = (data) => {
  formColumns.value = [];
  init();
  if (options.formOption.viewType === "tag" && currentAction.value !== "see") {
  } else {
    componentName.value =
      options.formOption.viewType === "drawer" ? "el-drawer" : "el-dialog";
    dataVisible.value = true;
  }
};
//关闭对话框
const close = () => {
  dataVisible.value = false;
  formColumns.value = [];
  formModel.value = {};
};

//表单提交
const submitForm = async () => {
  if (!wdFormRef.value) {
    console.error('wdFormRef 未绑定');
    return;
  }

  let formData;
  let isValid = false;

  try {
    formData = wdFormRef.value.getFormData();
    isValid = await wdFormRef.value.validateForm();
  } catch (err) {
    console.error('表单处理异常:', err);
    return;
  }

  if (!isValid) return false;

  let response;

  try {
    if (currentAction.value === 'add') {
      if (isFunction(options.beforeAdd)) await options.beforeAdd(formData);
      response = await options.add.api(formData);
      if (isFunction(options.afterAdd)) await options.afterAdd(response, formData);
    } else {
      if (isFunction(options.beforeEdit)) await options.beforeEdit(formData);
      const id = formData[options.pk];
      if (!id) {
        console.error('缺少主键，无法编辑');
        return;
      }
      response = await options.edit.api(id, formData);
      if (isFunction(options.afterEdit)) await options.afterEdit(response, formData);
    }
  } catch (err) {
    console.error('提交处理异常:', err);
    return;
  }

  if (response?.success) {
    message(response.message || `${actionTitle.value}成功！`, { type: 'success' });
    emit('success', response);
    close();
    return true;
  } else {
    console.warn('接口返回失败', response);
  }
};

//初始化
const init = async () => {
  dataLoading.value = true;
  //表单布局
  const layout = JSON.parse(JSON.stringify(options?.formOption?.layout ?? []));
  columns.value.map(async (item) => {
    await columnItemHandle(item);
  });
  if (isArray(layout) && layout.length > 0) {
  }
  dataLoading.value = false;
};
/**
 * 预处理表单字段
 * @param item
 */
const columnItemHandle = async (item) => {
  //排除 [ 操作栏 选项栏]
  const excludeColumns = ["__index", "__operation"];
  if (options.formExcludePk) excludeColumns.push(options.pk);
  //过滤不展示字段
  if (!formItemShow(item) || excludeColumns.includes(item.dataIndex)) return;
  formColumns.value.push(item);

  // 针对带点的数据处理
    if (item.dataIndex && item.dataIndex.indexOf('.') > -1) {
      formModel.value[item.dataIndex] = get(formModel.value, item.dataIndex)
    }

  // add 默认值处理
  if (currentAction.value === "add") {
    if (typeof item.addDefaultValue != "undefined") {
      formModel.value[item.dataIndex] = item.addDefaultValue;
    }
  }
  // edit 和 see 默认值处理
  if (currentAction.value === "edit") {
    if (item.editDefaultValue && isFunction(item.editDefaultValue)) {
      formModel.value[item.dataIndex] = await item.editDefaultValue(formModel.value);
    } else if (typeof item.editDefaultValue != "undefined") {
      formModel.value[item.dataIndex] = item.editDefaultValue;
    }
  }
  // 其他处理
  item.display = formItemShow(item);
  item.disabled = formItemDisabled(item);
  item.labelWidth = formItemLabelWidth(item);
  item.rules = getRules(item)
};
//格式化规则
const toRules = (rules) => {
  if (!rules) {
    return [];
  }

  if (isArray(rules)) {
    return rules.map((v) => ({ ...v }));
  }

  if (!rules.validator && isFunction(rules.validatorFormData)) {
    rules.validator = (value, cb) => {
      rules.validatorFormData(value, cb, form.value);
    };
  }
  return { ...rules };
};

// 是否显示表单元素
const formItemShow = (item) => {
  if (currentAction.value === "add") {
    return isFunction(item.addDisplay)
      ? item.addDisplay() !== false
      : item.addDisplay !== false;
  }
  if (currentAction.value === "edit" || currentAction.value === "see") {
    return isFunction(item.editDisplay)
      ? item.editDisplay(form.value) !== false
      : item.editDisplay !== false;
  }
  return item.display !== false;
};
//是否禁用表单元素
const formItemDisabled = (item) => {
  if (currentAction.value === "add" && !isUndefined(item.addDisabled)) {
    return isFunction(item.addDisabled) ? item.addDisabled() : item.addDisabled;
  }
  if (currentAction.value === "edit" && !isUndefined(item.editDisabled)) {
    return isFunction(item.editDisabled)
      ? item.editDisabled(form.value)
      : item.editDisabled;
  }
  if (currentAction.value === "see") {
    return true;
  }
  if (!isUndefined(item.disabled)) {
    return item.disabled;
  }
  return false;
};
//表单是否只读
const formItemReadonly = (item) => {
  if (currentAction.value === "add" && !isUndefined(item.addReadonly)) {
    return isFunction(item.addReadonly) ? item.addReadonly() : item.addReadonly;
  }
  if (currentAction.value === "edit" && !isUndefined(item.editReadonly)) {
    return isFunction(item.editReadonly)
      ? item.editReadonly(form.value)
      : item.editReadonly;
  }
  if (!isUndefined(item.readonly)) {
    return item.readonly;
  }
  return false;
};
//初始化表单label 宽度
const formItemLabelWidth = (item) => {
  return item.labelWidth ?? options.labelWidth ?? undefined;
};
//获取验证规则
const getRules = (item) => {
  if (currentAction.value === "add") {
    return toRules(item.addRules ?? item.commonRules ?? []);
  }
  if (currentAction.value === "edit") {
    return toRules(item.editRules ?? item.commonRules ?? []);
  }
};
provide("form", toRaw(formModel));
defineExpose({ add, edit, see, currentAction, formModel });
</script>
<template>
  <component
    :is="componentName"
    v-model="dataVisible"
    :width="options.formOption.width"
    :size="options.formOption.size?? '50%'"
    :fullscreen="options.formOption.isFull || false"
    :close-on-click-modal="false"
    :lock-scroll="true"
    :draggable="options.formOption.draggable??false"
    destroy-on-close
    top="5vh"
    class="__wd_form_dialog"
  >
    <template #header>
      <div class="el-dialog__title">{{ actionTitle }}</div>
      <button
        v-if="options.formOption.isFull || false"
        class="el-dialog__headerbtn"
        style="right: 51px"
        @click="tagSettingfullscreen = !tagSettingfullscreen"
      >
        <icon
          icon="ri-fullscreen-line"
          class="el-dialog__fullscreen el-dialog__close"
          :size="14"
        ></icon>
      </button>
    </template>
    <div class="__wd_form_dialog_content" v-loading="dataLoading">
      <wd-form
        v-model="formModel"
        :columns="formColumns"
        :options="formOptions"
        ref="wdFormRef"
      >
      <!-- 组件的插槽 -->
          <template v-for="slot in Object.keys($slots)" #[slot]="component">
            <slot :name="slot" v-bind="component" />
          </template>
      </wd-form>
    </div>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="close">关闭</el-button>
        <el-button type="primary" v-if="currentAction !== 'see'" @click="submitForm"> 保存 </el-button>
      </div>
    </template>
  </component>
</template>